package cz.zcu.fav.rat.ical;

import java.io.IOException;
import java.io.OutputStream;
import java.net.URI;
import java.util.Date;
import java.util.GregorianCalendar;
import java.util.List;

import net.fortuna.ical4j.data.CalendarOutputter;
import net.fortuna.ical4j.model.Calendar;
import net.fortuna.ical4j.model.DateTime;
import net.fortuna.ical4j.model.ValidationException;
import net.fortuna.ical4j.model.component.VAlarm;
import net.fortuna.ical4j.model.component.VEvent;
import net.fortuna.ical4j.model.parameter.Cn;
import net.fortuna.ical4j.model.parameter.Role;
import net.fortuna.ical4j.model.property.Action;
import net.fortuna.ical4j.model.property.Attendee;
import net.fortuna.ical4j.model.property.CalScale;
import net.fortuna.ical4j.model.property.Description;
import net.fortuna.ical4j.model.property.ProdId;
import net.fortuna.ical4j.model.property.Trigger;
import net.fortuna.ical4j.model.property.Uid;
import net.fortuna.ical4j.model.property.Version;

import org.apache.log4j.Logger;
import org.joda.time.LocalDateTime;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;

import cz.zcu.fav.rat.beans.Period;
import cz.zcu.fav.rat.beans.PickAction;
import cz.zcu.fav.rat.beans.Reservation;
import cz.zcu.fav.rat.beans.ReturnAction;
import cz.zcu.fav.rat.dataaccess.service.ReservationService;
import cz.zcu.fav.rat.managed.locale.LocaleMessageFactory;

@Component
public class ICalUserGenerator
{
	@Autowired
	ReservationService reservationService;
	private Logger logger = Logger.getLogger(ICalUserGenerator.class);

	public void createICal(OutputStream browserStream, Integer id)
	{
		try
		{
			Calendar calendar = new Calendar();
			calendar.getProperties().add(
					new ProdId("-//Ben Fortuna//iCal4j 1.0//EN"));
			calendar.getProperties().add(Version.VERSION_2_0);
			calendar.getProperties().add(CalScale.GREGORIAN);

			List<Reservation> list = reservationService
					.getAllReservationsByUserId(id);

			for (Reservation reservation : list)
			{
				for (Period period : reservation.getPeriods())
				{
					String eventName = reservation.getObject().getName();
					DateTime start = new DateTime(period.getFromDate().toDate());
					DateTime end = new DateTime(period.getToDate().toDate());
					VEvent reservationEvent = new VEvent(start, end, eventName);
					Uid uid = new Uid(period.getId() + "");
					reservationEvent.getProperties().add(uid);
					calendar.getComponents().add(reservationEvent);
					if (period.isValid()
							&& period.getPickAction() == PickAction.NOT_PICKED
							&& period.getFromDate()
									.isAfter(LocalDateTime.now()))
					{
						createAlarm(
								reservation.getObject().getName()
										+ " "
										+ LocaleMessageFactory
												.getLocale("properties.period.state.start"),
								period.getFromDate().toDate(), reservationEvent);
					}

					if (period.isValid()
							&& period.getReturnAction() == ReturnAction.NOT_RETURNED
							&& period.getToDate().isAfter(LocalDateTime.now()))
					{
						createAlarm(
								reservation.getObject().getName()
										+ " "
										+ LocaleMessageFactory
												.getLocale("properties.period.state.end"),
								period.getToDate().toDate(), reservationEvent);
					}

				}
			}
			CalendarOutputter outputter = new CalendarOutputter();
			outputter.output(calendar, browserStream);
		} catch (IOException | ValidationException e)
		{
			logger.error("error in ical ex", e);
		}

	}

	protected void createAlarm(String message, Date date,
			VEvent reservationEvent)
	{
		VAlarm alarm = new VAlarm();
		Action action = new Action("DISPLAY");
		alarm.getProperties().add(action);
		Trigger trigger = new Trigger(new DateTime(date));
		alarm.getProperties().add(trigger);
		Description description = new Description(message);
		alarm.getProperties().add(description);
		reservationEvent.getAlarms().add(alarm);
	}

}
